/*
 * EchequeClient.java
 *
 * Created on April 27, 2007, 8:38 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

/**
 *
 * @author SAAD
 */

package eCheque;

import java.net.*;
import java.io.*;
import javax.swing.JOptionPane;

public class EchequeClient implements Runnable {

	public static final int PORT_NUMBER = 8189;
	public static final int ACTION_REGISTER = 0;
	public static final int ACTION_DEPOSIT = 1;
	public static final int ACTION_CANCEL = 2;
	public static final int ACTION_BALANCE = 3;
	public static final int ACTION_DELETE = 4;

	private Socket ClientConnection;
	private ObjectInputStream SocketInputObject;
	private ObjectOutputStream SocketOutputObject;
	private InputStream SocketInput;
	private OutputStream SocketOutput;
	private DigitalCertificate clientCerit;
	private EChequeRegisteration registrationData;
	private ECheque depositCheque;
	private String hostname;
	private int portID;
	private int bankmode;
	private boolean getServerConnection;
	private boolean getSocketConnection;
	private ResponseHandler handler;

	public EchequeClient(int port, int mode, String host,
			EChequeRegisteration register, DigitalCertificate DC, ResponseHandler handler) {
		portID = port;
		bankmode = mode;
		hostname = host;
		registrationData = register;
		clientCerit = DC;
		this.handler = handler;
	}

	public EchequeClient(int port, int mode, String host,
			EChequeRegisteration register, ECheque chq) {
		portID = port;
		bankmode = mode;
		hostname = host;
		registrationData = register;
		depositCheque = chq;
	}

	public EchequeClient(int port, int mode, EChequeRegisteration account) {
		portID = port;
		bankmode = mode;
		hostname = account.getBankAddress();
		registrationData = account;
	}

	private void ConnectToServer() throws Exception {

		ClientConnection = new Socket(InetAddress.getByName(hostname), portID);
		getServerConnection = true;
	}

	private void getSocketStream() throws Exception {

		SocketInput = ClientConnection.getInputStream();
		SocketOutput = ClientConnection.getOutputStream();
		SocketOutput.flush();
		SocketInputObject = new ObjectInputStream(
				ClientConnection.getInputStream());
		SocketOutputObject = new ObjectOutputStream(
				ClientConnection.getOutputStream());
		SocketOutputObject.flush();

		getServerConnection = true;
	}

	private void CloseConnection() {
		try {
			if (getSocketConnection) {
				SocketInput.close();
				SocketOutput.close();
				SocketInputObject.close();
				SocketOutputObject.close();
			}
			if (getServerConnection) {
				ClientConnection.close();
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null,
					"Illegal close for communication channel",
					"Connection Error", JOptionPane.ERROR_MESSAGE);
		}
	}

	private EChequeResponse processBankConection() throws IOException,
			ClassNotFoundException, DuplicateAccountException {
		SocketOutputObject.writeInt(bankmode);
		SocketOutputObject.flush();

		if (bankmode == ACTION_REGISTER) {
			SocketOutputObject.writeObject(registrationData);
			SocketOutputObject.flush();
			SocketOutputObject.writeObject(clientCerit);
			SocketOutputObject.flush();
		} else if (bankmode == ACTION_DEPOSIT) {
			SocketOutputObject.writeObject(depositCheque);
			SocketOutputObject.flush();
			SocketOutputObject.writeObject(registrationData.getAccountNumber());
			SocketOutputObject.flush();
		} else if (bankmode == ACTION_CANCEL) {
			SocketOutputObject.writeObject(depositCheque);
			SocketOutputObject.flush();
		} else  if(bankmode == ACTION_BALANCE) {
			SocketOutputObject.writeObject(registrationData.getAccountNumber());
			SocketOutputObject.flush();
		} else if(bankmode == ACTION_DELETE) {
			SocketOutputObject.writeObject(registrationData.getAccountNumber());
			SocketOutputObject.flush();
		}

		EChequeResponse response = (EChequeResponse) SocketInputObject
				.readObject();
		return response;
	}

	public void RunClient() {
		EChequeResponse response = null;
		try {
			ConnectToServer();
			getSocketStream();
			response = processBankConection();
		}

		catch (Exception error) {
			JOptionPane.showMessageDialog(null, error.getMessage(),
					"Connection Error", JOptionPane.ERROR_MESSAGE);

		}

		finally {
			CloseConnection();
		}
		if(handler != null) {
			handler.handleResponse(response);
		}
	}

	public void run() {
		RunClient();
	}

}
